package cn.edu.hitwh.kanlema.service.impl;

import cn.edu.hitwh.kanlema.constant.UserConstants;
import cn.edu.hitwh.kanlema.dto.LoginFormDTO;
import cn.edu.hitwh.kanlema.dto.UserDTO;
import cn.edu.hitwh.kanlema.exception.ApiException;
import cn.edu.hitwh.kanlema.util.PhoneMessageUtil;
import cn.edu.hitwh.kanlema.constant.RedisConstants;
import cn.edu.hitwh.kanlema.util.RedisCache;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.edu.hitwh.kanlema.entity.User;
import cn.edu.hitwh.kanlema.mapper.UserMapper;
import cn.edu.hitwh.kanlema.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author vvcoder
 * @since 2025-8-18
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private RedisCache redisCache;

    @Override
    public void sendCode(String phone) {
        String code = RandomUtil.randomNumbers(UserConstants.VERIFY_CODE_LEN);
        redisCache.setValue(RedisConstants.LOGIN_CODE_KEY + phone, code, RedisConstants.LOGIN_CODE_TTL, TimeUnit.MINUTES);
        PhoneMessageUtil.sendCode(phone, code);
    }

    @Override
    public String login(LoginFormDTO loginForm) {
        // 校验验证码
        String code = redisCache.getValue(RedisConstants.LOGIN_CODE_KEY + loginForm.getPhone());
        if (code == null || !code.equals(loginForm.getCode())) {
            throw new ApiException(HttpStatus.BAD_REQUEST.value(), "验证码错误");
        }

        // 登录或注册
        User user = lambdaQuery().eq(User::getPhone, loginForm.getPhone()).one();
        if (user == null) {
            // 注册
            user = new User();
            user.setPhone(loginForm.getPhone());
            user.setPassword(loginForm.getPassword());
            if (StrUtil.isBlank(user.getPassword())) {
                user.setPassword("");
            }
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            boolean saved = false;
            for (int i = 0; i < UserConstants.USER_REGISTER_MAX_TRY_COUNT; i++) {
                String nickName = UserConstants.USER_NICK_NAME_PREFIX + RandomUtil.randomString(UserConstants.USER_NICK_NAME_SUFFIX_LEN);
                if (lambdaQuery().eq(User::getNickName, nickName).count() == 0) {
                    user.setNickName(nickName);
                    save(user);
                    saved = true;
                    break;
                }
            }
            if (!saved) {
                throw new ApiException(HttpStatus.BAD_REQUEST.value(), "注册失败");
            }
        }

        // 生成 tokrn
        String token = UUID.randomUUID().toString();
        // 存储 token 到 redis
        String tokenKey = RedisConstants.LOGIN_USER_KEY + token;
        redisCache.setObject(tokenKey, BeanUtil.copyProperties(user, UserDTO.class));
        redisCache.expire(tokenKey, RedisConstants.LOGIN_USER_TTL, TimeUnit.SECONDS);
        return token;
    }

    @Override
    public void logout(String token) {
        if (StrUtil.isBlank(token)) {
            return;
        }
        redisCache.delete(RedisConstants.LOGIN_USER_KEY + token);
    }
}
